<template>
  <div class="upload">
    <div>
      情况一：监视ref定义的基本数据类型，<span style="color: red">
        并且可以停止监听在满足一定条件下</span
      >
    </div>
    <div>sum:{{ sum }}</div>
    <button @click="sum += 1">+1</button>
    <hr />

    <div>情况二：监视 ref 定义的 对象数据 类型</div>
    <br />
    <div style="color: red">
      备注：如果监视的是整个对象时，整个对象发生变化才会触发,如果想要监视对象内部的某个属性的变化,则需要手动开启深度监视
    </div>
    <br />
    <div style="color: red">
      *注意:如果修改的是整个对象，新旧值不一样，如果修改的是对象中的某一个属性新旧就是同一个值(新值)
    </div>
    <br />

    <div>
      姓名 <span>{{ persons.name }}</span>
    </div>
    <div>
      年龄 <span>{{ persons.age }}</span>
    </div>
    <button @click="changeName">修改姓名</button>
    <button @click="changeAge">修改年龄</button>
    <button @click="changePerson">修改整个人</button>

    <hr />

    <div>情况三：监视 reactive 定义的 对象类型 数据</div>
    <br />
    <p style="color: red">注意：1.默认开启深度监视并且不可以关闭深度监视</p>
    <br />
    <p style="color: red">注意：2.如果要监修改整个对象需要用Object.assign</p>
    <br />
    <p style="color: red">
      注意：3.不管是修改整个对象还是对象中的某个属性
      新旧值都是一样的（因为地址值没变）
    </p>

    <div>
      姓名 <span>{{ persond.name }}</span>
    </div>
    <div>
      年龄 <span>{{ persond.age }}</span>
    </div>
    <div>
      数字 <span>{{ numbers.number }}</span>
    </div>
    <button @click="changeName1">修改姓名</button>
    <button @click="changeAge1">修改年龄</button>
    <button @click="changePerson1">修改整个人</button>
    <button @click="addNum">数字加一</button>

    <hr />
    <div>情况四:监视 对象类型 中的某一个属性(其他的不监视)</div>
    <p style="color: red">
      注意:1.监视的是
      响应式中对象中的某个属性,且该属性是基本数据类型，要写成函数式,并且新旧是不一样
    </p>
    <p style="color: red">
      注意:2.监视的是
      响应式中对象中的某个属性,且该属性是对象类型，建议也写成函数式,如果要监视整个对象的属性，开启深度监听即可
    </p>
    <p style="color: red">注意:3.监视多个数据用数组包裹</p>

    <div>姓名:{{ car.name }}</div>
    <div>年龄:{{ car.age }}</div>
    <div>C1:{{ car.car.c1 }}</div>
    <div>C2:{{ car.car.c2 }}</div>
    <button @click="changeName3">修改姓名</button>
    <button @click="changeAge3">修改年龄</button>
    <button @click="changeC1">修改c1</button>
    <button @click="changeC2">修改c2</button>
    <button @click="changeCar">修改整个车</button>
  </div>
</template>

<script setup lang="ts">
import { reactive, ref, watch } from "vue";
import { type PersonType } from "./type/inde";
/**
 * watch 情况一
 * 监视 ref 定义的 基本数据 类型，并且可以停止监听在满足一定条件下
 */
const sum = ref(0);
const stopWatch = watch(sum, (newV, oldV) => {
  console.log(newV, oldV);
  if (newV >= 10) {
    stopWatch();
    stopWatch(); //停止监听
  }
});

/********************************************************** */

/**
 * watch 情况二
 * 监视 ref 定义的 对象数据 类型，
 */
const persons = ref({
  name: "小红",
  age: 25,
});

let changeName = () => {
  persons.value.name += "~";
};

const changeAge = () => {
  persons.value.age += 1;
};

const changePerson = () => {
  persons.value = { name: "小芬", age: 25 };
};

/**
 * 这里监视的是整个对象的地址,整个对象发生变化才会触发,如果想要监视对象内部的某个属性的变化,则需要手动开启深度监视
 * 注意:如果修改的是整个对象，新旧值不一样，如果修改的是对象中的某一个属性新旧就是同一个值(新值)
 */

watch(
  persons,
  (newV, oldV) => {
    console.log("person变化了", newV, oldV);
  },
  { deep: true, immediate: true }
);

/******************************************************** */
/**
 * watch 情况三
 * 监视 reactive 定义的 对象数据 类型，
 */

let persond = reactive<PersonType>({
  name: "小红",
  age: 4,
});

const numbers = reactive({
  number: 5,
});

const changeName1 = () => {
  persond.name += "~";
};
const changeAge1 = () => {
  persond.age += 1;
};

const changePerson1 = () => {
  Object.assign(persond, { name: "小芬", age: 25 });
};

const addNum = () => {
  numbers.number += 1;
};
const stop2 = watch(persond, (newV, oldV) => {
  console.log("person变化了aaaaa", newV, oldV);
  if (newV.name == "小芬") {
    stop2(); //当满足一定条件停止监听
  }
});

const stop = watch(numbers, (value) => {
  console.log("数字改变了", value);
  if (value.number == 8) {
    stop(); //当满足一定条件停止监听
  }
});

/*********************************************** */

/**
 * 情况四 监视 对象类型 中的某一个属性(其他的不监视)
 */

const car = reactive({
  name: "张三",
  age: 6,
  car: {
    c1: "金吉拉",
    c2: "宝马",
  },
});

const changeName3 = () => {
  car.name = "李四";
};
const changeAge3 = () => {
  car.age = 52;
};
const changeC1 = () => {
  car.car.c1 = "宝马";
};
const changeC2 = () => {
  car.car.c2 = "红旗";
};
const changeCar = () => {
  car.car = { c1: "路虎", c2: "劳斯莱斯" };
};

watch(
  () => car.car,
  (newV, oldV) => {
    console.log("改变了", newV, oldV);
  },
  { deep: true }
);
</script>

<style scoped lang="scss">
@import "index.module.scss";
</style>
